package jmars.mobile.worker.gephi;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import jmars.mobile.common.Investigator;
import jmars.mobile.datainvestigation.Summary;

/**
 * select [group columns], count, sum(target column1) [, sum(target column2)...] 
 * from data group by [group columns] 
 * order by count desc
 * 
 * @author Jan
 *
 */
public class AllNodes implements Investigator {

	@Override
	public Long compute(File[] files, FileWriter writer) throws IOException {
		Long total = 0L;
		FileInputStream fis;
		BufferedReader reader;
		String row;
		String[] cols;
		Map<String,Integer> distinct=new HashMap<String,Integer>();
		Map<String,Map<Integer,Double>> nodeMap=new HashMap<String,Map<Integer,Double>>();
		Map<Integer,Double> eachNode;
		String nodeId;
		DecimalFormat df = new DecimalFormat();
		df.applyPattern("0");
		Double tempD;
		for(File inputFile:files){
			fis = new FileInputStream(inputFile);
			reader = new BufferedReader(new InputStreamReader(fis));
			while((row=reader.readLine())!=null){
				cols=row.split(Summary.columnSeperator);
				if(Summary.filterRow(cols,true,true)) continue;
				nodeId="";
				for(Integer idx:Summary.groupColumnIdx){
					nodeId=idx+"#"+cols[idx];
					if(!nodeMap.containsKey(nodeId)){
						distinct.put(nodeId,1);
						eachNode = new HashMap<Integer,Double>();
						nodeMap.put(nodeId, eachNode);
					}else{
						eachNode = nodeMap.get(nodeId);
						distinct.put(nodeId,distinct.get(nodeId)+1);
					}
					for(Integer tidx:Summary.targetColumnIdx){
						tempD=Double.parseDouble(cols[tidx]);
						if(!eachNode.containsKey(tidx)){
							eachNode.put(tidx, tempD);
						}else{
							eachNode.put(tidx, eachNode.get(tidx)+tempD);
						}
					}
					
				}
				
				total++;
			}
			reader.close();
			fis.close();
			System.out.println(inputFile.getName()+" finished at "+total);
		}
		System.out.print("%"+Summary.groupColumns+":"+df.format(distinct.size())+"\r\n");
		System.out.print("%total:"+df.format(total)+"\r\n");
		if(distinct.size()<=1000000){
			ArrayList<Entry<String,Integer>> l = new ArrayList<Entry<String,Integer>>(distinct.entrySet());    
	          
	        Collections.sort(l, new Comparator<Map.Entry<String, Integer>>() {    
	            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {    
	                return (int) (o2.getValue() - o1.getValue());    
	            }    
	        });

	        System.out.print("%*****************details******************\r\n%");
	        writer.write("Id,Label,Type");
			for(Integer idx:Summary.targetColumnIdx){
				writer.write(","+Summary.columns[idx]);
			}
			writer.write("\r\n");
	        for(String key : nodeMap.keySet()) {
	        	writer.write(key+","+key.substring(key.indexOf("#")+1)+","+Summary.columns[Integer.parseInt(key.substring(0,key.indexOf("#")))]);
	            for(Integer idx:Summary.targetColumnIdx){
		            writer.write(","+df.format(nodeMap.get(key).get(idx)));
	            }
	            writer.write("\r\n");
	        }
	        
		}
		return total;
	}

}
